using System;
using System.Collections.Generic;
using System.Text;
using System.CodeDom.Compiler;

namespace SharpMud.Server.Systems.Scripting.Processing
{
    internal class ScriptCompileResults : IScriptCompileResults
    {
        internal List<IScriptCompileMessage> _CompileMessages;
        internal ICompiledScriptHandle _CompiledScriptHandle;

        internal ScriptCompileResults()
        {
            _CompileMessages = new List<IScriptCompileMessage>();
            _CompiledScriptHandle = null;
        }

        #region IScriptCompileResults Members

        public IScriptCompileMessage[] GetCompileMessages()
        {
            return _CompileMessages.ToArray();
        }

        public int GetMessageTypeCount(ScriptCompileMessageType messageType)
        {
            int counter = 0;
            foreach (IScriptCompileMessage scm in this._CompileMessages)
            {
                if (scm.MessageType == messageType)
                    counter++;
            }
            return counter;
        }

        public bool WasSuccessful
        {
            get
            {
                if (GetMessageTypeCount(ScriptCompileMessageType.Error) == 0)
                    return true;
                return false;
            }
        }

        public ICompiledScriptHandle CompiledScriptHandle
        {
            get { return _CompiledScriptHandle; }
        }

        #endregion
    }

    public class ScriptCompileMessage : IScriptCompileMessage
    {
        internal string _ErrorText;
        internal string _ErrorNumber;
        internal ScriptCompileMessageType _MessageType;
        internal int _Line;
        internal int _Column;
        private CompilerError _CompilerError;

        internal ScriptCompileMessage()
            :this(ScriptCompileMessageType.Other,string.Empty)
        {
        }

        public ScriptCompileMessage(ScriptCompileMessageType messageType, string errorText)
            :this(messageType,errorText,String.Empty)
        {
        }

        public ScriptCompileMessage(ScriptCompileMessageType messageType, string errorText, string errorNumber)
            :this(messageType,errorText,errorNumber,-1,-1)
        {
        }

        public ScriptCompileMessage(ScriptCompileMessageType messageType, string errorText, string errorNumber, int line)
            : this(messageType, errorText, errorNumber, line, -1)
        {
        }

        public ScriptCompileMessage(ScriptCompileMessageType messageType, string errorText, string errorNumber, int line, int column)
        {
            this._MessageType = messageType;
            this._ErrorText = errorText;
            this._ErrorNumber = errorNumber;
            this._Line = line;
            this._Column = column;
        }

        #region IScriptCompileMessage Members

        string IScriptCompileMessage.ErrorText
        {
            get { return _ErrorText; }
        }

        string IScriptCompileMessage.ErrorNumber
        {
            get { return _ErrorNumber; }
        }

        ScriptCompileMessageType IScriptCompileMessage.MessageType
        {
            get { return _MessageType; }
        }

        int IScriptCompileMessage.Line
        {
            get { return _Line; }
        }

        int IScriptCompileMessage.Column
        {
            get { return _Column; }
        }

        #endregion

        internal static IScriptCompileMessage FromCompilerError(CompilerError compilerError)
        {
            ScriptCompileMessageType scmt = ScriptCompileMessageType.Other;
            if (compilerError.IsWarning)
                scmt = ScriptCompileMessageType.Warning;
            else
                scmt = ScriptCompileMessageType.Error;

            ScriptCompileMessage scm = new ScriptCompileMessage(scmt, compilerError.ErrorText, compilerError.ErrorNumber, compilerError.Line, compilerError.Column);
            scm._CompilerError = compilerError;

            return scm;
        }
    }
}
